昨天我在圖片上傳功能的時候,讓圖片路徑存入資料庫,但是在資料取出時,圖片路徑要轉變為前端可以讀取的網址,需要程式進一步處理
存入資料庫的圖片路徑
在前端畫面中顯示的路徑
//controller
public function create(Group $group)
{
$group['image_path'] = Storage::url($group['image_path']);
// 將路徑用 Storage::url() 轉換為前端可讀取的位置
// dd()結果如圖
return view('group.createProduct', [
'group' => $group,
]);
}
為了解決這類問題, Laravel 有 Mutator 及 Accessor 功能,可以針對資料在存進資料庫及取出資料庫的時候,進行資料的處理,可能包含格式轉換或回傳自定義的內容。
純後端工程師在處理回傳資料的轉換時,可以直接透過 Resource Collection 進行處理,可能是因為這樣所以我問了幾位夥伴好像都不太常用。
Resource Collection 詳細可參考:https://ithelp.ithome.com.tw/articles/10333916
而如果前後端不分離的網站,就不會使用 Resource Collection,必須使用其他方法處理。
Laravel 在第九版時針對 Accessor & Mutator 寫法進行大改版,但是有相容舊的版本,所以也是可以用的
// Model 裡面加入
public function setFirstNameAttribute($value)
{
// function 命名為 get (Mutator) 或 set (Accessor) + table 欄位名稱改為小駝峰 + Attribute
$this->attributes['first_name'] = strtolower($value);
}
Laravel 9 以後將 Mutator 及 Accessor 寫在一起,不用分開 function,可以更簡潔地表示。
protected function imagePath(): Attribute
{
return Attribute::make(
set: fn(string $value) => Storage::url($value),
);
}
Illuminate\Database\Eloquent\Casts\Attribute
Attribute::make()
方法Attribute::make()
裡面用 named argument 方式寫入,set 為 Mutator、get 為 Accessor存入資料庫時,圖片路徑就已經加入了 Storage::url() 的效果
protected function imagePath(): Attribute
{
return Attribute::make(
get: fn(string $value) =>
str_starts_with($value, 'http') ? $value : Storage::url($value),
// 如果 image_path 欄位不是以 http 開頭的話,就讓值經過 Storage::url() 轉換
);
}
Accessor 使用的方式跟 Mutator 相同,只有 named argument 方式改為 get
id = 36 的 image_path 欄位為圖片路徑、 id = 37 的 image_path 欄位為網址
使用 Accessor 後,id = 36 的 image_path 轉為 urI
而原本 id = 37 的 image_path 為網址,使用後不改變